1 /* 2 * Collie - An asynchronous event-driven network framework using Dlang development 3 * 4 * Copyright (C) 2015-2017 Shanghai Putao Technology Co., Ltd 5 * 6 * Developer: putao's Dlang team 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 module collie.net.server.connection; 12 13 import kiss.net.TcpStream; 14 import kiss.event.timer.common; 15 import kiss.util.timer; 16 import kiss.event; 17 import kiss.event.task; 18 import kiss.logger; 19 20 21 abstract class ServerConnection : WheelTimer 22 { 23 this(TcpStream socket) 24 { 25 resetSocket(socket); 26 } 27 28 final void resetSocket(TcpStream socket) 29 { 30 if(_socket !is null){ 31 _socket.onClosed(null); 32 _socket.onDataReceived(null); 33 _socket = null; 34 } 35 if(socket !is null){ 36 _socket = socket; 37 _loop = cast(EventLoop) socket.eventLoop; 38 _socket.onClosed(&doClose); 39 _socket.onDataReceived(&onRead); 40 } 41 } 42 43 final bool isAlive() @trusted { 44 return _socket && _socket.isRegistered; 45 } 46 47 final bool active() @trusted 48 { 49 if(_socket is null) 50 return false; 51 _socket.start(); 52 onActive(); 53 return true; 54 } 55 56 final void write(ubyte[] data, DataWrittenHandler cback = null) @trusted 57 { 58 write(new SocketStreamBuffer(data,cback)); 59 } 60 61 final void write(StreamWriteBuffer buffer) 62 { 63 if (_loop.isInLoopThread()) { 64 _postWriteBuffer(buffer); 65 } else { 66 _loop.postTask(newTask(&_postWriteBuffer, buffer)); 67 } 68 } 69 70 final void restTimeout() @trusted 71 { 72 if(_loop.isInLoopThread()){ 73 rest(); 74 } else { 75 _loop.postTask(newTask(&rest,0)); 76 } 77 } 78 pragma(inline) 79 final void close() @trusted 80 { 81 _loop.postTask(newTask(&_postClose)); 82 } 83 84 final @property TcpStream tcpStream()@safe { 85 assert(_socket !is null); 86 return _socket; 87 } 88 protected: 89 void onActive() nothrow; 90 void onClose() nothrow; 91 void onRead(in ubyte[] data) nothrow; 92 93 private: 94 final void _postClose(){ 95 if(_socket) 96 _socket.close(); 97 } 98 99 final void _postWriteBuffer(StreamWriteBuffer buffer) 100 { 101 if (_socket) { 102 version (CollieDebugMode) logDebug("posting data... ", buffer); 103 rest(); 104 _socket.write(buffer); 105 } else 106 { 107 version (CollieDebugMode) logDebug("post done."); 108 buffer.doFinish(); 109 } 110 } 111 112 final void doClose() 113 { 114 stop(); 115 onClose(); 116 } 117 private: 118 TcpStream _socket; 119 EventLoop _loop; 120 } 121